// server.js

const express = require('express');
const CryptoJS = require('crypto-js');
const forge = require('node-forge');

const app = express();
app.use(express.json());

// =============== 工具函数 ===============

// 字符串转 Hex
function convertToHex(str) {
    if (!str) return '';
    let hex = '';
    for (let i = 0; i < str.length; i++) {
        const code = str.charCodeAt(i).toString(16);
        hex += code.length === 1 ? '0' + code : code;
    }
    return hex;
}

// AES-CBC 加密
function aesEncrypt(data, keyStr) {
    const hexKey = convertToHex(keyStr).substring(0, 32).padEnd(32, '0');
    const key = CryptoJS.enc.Hex.parse(hexKey);
    const iv = CryptoJS.enc.Hex.parse(hexKey); // IV = Key（不推荐，但原逻辑如此）

    const encrypted = CryptoJS.AES.encrypt(data, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });

    return encrypted.toString();
}

// RSA 公钥加密（使用 node-forge）
const publicKeyPem = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCjYYIy9Are9QPRDOVug4e6Fdz
8HK2HGyajKR4N8Wb/bB9gwXnieXqj4Mya0nLd6nBcBPN6qUJ0R7p5Cv6aPqQsc7p
WfAxPr41GvcOlGixLtpLHLUH9m0093YEBhu4F7pKu0TZTQIPZINWUa1SLjQD/bcB
lcaQyWbk6qJhSJFYkwIDAQAB
-----END PUBLIC KEY-----`;

function rsaEncrypt(data) {
    const publicKey = forge.pki.publicKeyFromPem(publicKeyPem);
    const encrypted = publicKey.encrypt(data, 'RSAES-PKCS1-V1_5');
    return forge.util.encode64(encrypted);
}

// 生成随机 AES 密钥（16 字符）
function generateAesKey(length = 16) {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    for (let i = 0; i < length; i++) {
        result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
}

// 主加密函数 Or
function Or(data) {
    const aesKey = generateAesKey();
    const encryptedKey = rsaEncrypt(aesKey);
    const encryptedData = aesEncrypt(data, aesKey);

    return {
        k: encryptedKey,
        v: 1,
        d: encryptedData,
        i: encryptedKey
    };
}

// password 加密
function encryptPassword(password) {
    return `adat@${JSON.stringify(Or(password))}`;
}

// 整体加密
function encryptAll(loginName, password) {
    const requestData = {
        requestData: {
            loginName,
            password: encryptPassword(password),
            areaCode: '86'
        },
        commonParams: {
            bizId: 'jiaoyimao',
            appCode: 'JYM_H5',
            clientAppCode: 'JYM_H5'
        }
    };

    return Or(JSON.stringify(requestData));
}


app.post('/encrypt', (req, res) => {
    const { loginName, password } = req.body;

    if (!loginName || !password) {
        return res.status(400).json({ error: 'Missing loginName or password' });
    }

    try {
        const result = encryptAll(loginName, password);
        res.json(result);
    } catch (err) {
        console.error('Encryption error:', err);
        res.status(500).json({ error: 'Encryption failed', message: err.message });
    }
});

app.get('/health', (req, res) => {
    res.json({ status: 'ok', timestamp: new Date().toISOString() });
});


const PORT = process.env.PORT || 9000;
const HOST = '0.0.0.0';
app.listen(PORT, () => {
    console.log(`交易猫加密服务已启动: http://${HOST}:${PORT}`);
    console.log(`POST /encrypt { "loginName": "xxx", "password": "xxx" }`);
});